package com.example.mydownloader.data.login

import android.util.Base64
import com.example.mydownloader.config.globalConfig.UrlConfig
import com.example.mydownloader.data.model.inputdata.LoggedInUser
import com.example.mydownloader.data.model.inputdata.ResponseTemplate
import com.example.mydownloader.data.model.outputdata.LoginData
import com.example.mydownloader.myconst.ResponseMessage
import com.example.mydownloader.myconst.TransmissionData
import com.example.mydownloader.mymodule.encrypt.AESCryptUtil
import com.example.mydownloader.mymodule.gson.GsonUtil
import com.example.mydownloader.mymodule.http.HttpUtil
import com.example.mydownloader.mymodule.http.HttpUtil.okHttpClient
import com.example.mydownloader.mymodule.log.LogUtil
import com.example.mydownloader.mymodule.sharedpreferences.SPUtil

/**
 * Class that handles authentication login credentials and retrieves user information.
 */
class LoginDataSource {

    private var sessionId: String = ""

    fun login(username: String, password: String): Result<LoggedInUser> {
        // 登录预请求
        val preRequest = HttpUtil.createGetRequest(
            UrlConfig.preRequestUrl, null, null
        )
        val preResponse = okHttpClient.newCall(preRequest).execute()
        val preResult = preResponse.body!!.string()
        LogUtil.d("preResponse = $preResult")
        val responseTemplate =
            GsonUtil.toAny(preResult, ResponseTemplate::class.java)
        if (responseTemplate == null) {
            return Result.Error("Login failed Cause by pre-request failed")
        } else {
            if (responseTemplate.message == ResponseMessage.Success.PUBLIC_KEY_CREATED) {
                val publicKeyString = responseTemplate.data as String
                SPUtil.setString(TransmissionData.RSA_PUBLIC_KEY, publicKeyString)
                val aesKey = AESCryptUtil.generateKey()
                val securityKey = Base64.encode(aesKey.key, Base64.NO_WRAP)
                val iv = Base64.encode(aesKey.iv, Base64.NO_WRAP)
                SPUtil.setString(TransmissionData.AES_KEY, securityKey.toString(Charsets.UTF_8))
                SPUtil.setString(TransmissionData.AES_IV, iv.toString(Charsets.UTF_8))
                val cookies = preResponse.headers("Set-Cookie")
                val session = cookies[0]
                sessionId = session.substring(0, session.indexOf(";"))
                // 登录请求
                val loginResult = HttpUtil.postJson(
                    url = UrlConfig.loginUrl,
                    data = LoginData(username, password),
                    headers = hashMapOf(
                        "Cookie" to (sessionId)
                    )
                )
                LogUtil.d("loginResult = $loginResult")
                val loggedInUser =
                    GsonUtil.toAny(loginResult, LoggedInUser::class.java)
                if (loggedInUser != null) {
                    return Result.Success(loggedInUser)
                }
            }
            return Result.Error("Login failed.")
        }
    }

    fun logout() {
        // TODO: revoke authentication
    }
}